﻿using AutoMapper;
using Chat.EntityFrameworkCore;
using Cx.NetCoreUtils.Exceptions;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Xiao.Application.Dto;
using Xiao.Code.DbEnum;
using Xiao.Code.Entities.User;
using Xiao.Code.Entities.Users;
using Xiao.EntityFrameworkCore.Core;
using Xiao.EntityFrameworkCore.Repository;
using Xiao.EntityFrameworkCore.Repository.User;

namespace Xiao.Application.Services.User
{
    public interface IFriendRecordService
    {
        /// <summary>
        /// 创建好友申请
        /// </summary>
        /// <param name="friend"></param>
        /// <returns></returns>
        Task<Guid> ApplyForFrien(FriendRecordDto friend);
        Task<bool> ApplicationStatus(Guid id,sbyte statue);
        Task<Tuple<IList<FriendRecordDto>, int>> GetFriendRecordsList(Guid userId, sbyte statue, int pageNo, int pageSize);
    }
    public class FriendRecordService : BaseService<FriendRecord>, IFriendRecordService
    {
        private readonly IMapper _mapper;
        private readonly IFriendsRepository _friendsRepository;
        private readonly IConsumerRepository _consumerRepository;
        public FriendRecordService
            (IMapper mapper,
            IFriendsRepository friendsRepository,
            IConsumerRepository consumerRepository,
            IUnitOfWork<MasterDbContext> unitOfWork,
            IMasterDbRepositoryBase<FriendRecord> currentRepository)
            : base(unitOfWork, currentRepository)
        {
            _mapper = mapper;
            _friendsRepository = friendsRepository;
            _consumerRepository = consumerRepository;
        }

        public async Task<bool> ApplicationStatus(Guid id, sbyte statue)
        {
            var data =await currentRepository.FindAll(a => a.Id == id)
                .FirstOrDefaultAsync();
            if ((FriendStatusEnum)statue == FriendStatusEnum.InThings) throw new BusinessLogicException("申请状态错误");
            if (data == null) throw new BusinessLogicException("未发起好友申请");
            if (data.FriendStatus == FriendStatusEnum.Pass) throw new BusinessLogicException("好友申请已经通过");
            if(data.FriendStatus == FriendStatusEnum.InThings)
            {
                unitOfWork.BeginTransaction();
                data.FriendStatus = (FriendStatusEnum)statue;
                if((FriendStatusEnum)statue == FriendStatusEnum.Pass)
                {
                    var friend = new Friends
                    {
                        ConsumerId = data.ProposerId,
                        FriendId = data.RespondentId
                    };

                    var friends = new Friends
                    {
                        FriendId = data.ProposerId,
                        ConsumerId= data.RespondentId
                    };
                    friend =await _friendsRepository.AddAsync(friend);
                    friends = await _friendsRepository.AddAsync(friends);
                }
                currentRepository.Update(data);
                 unitOfWork.CommitTransaction();
                return true;
            }
            else
            {
                throw new BusinessLogicException("当前申请状态不是申请中处理异常");
            }
        }

        public async Task<Guid> ApplyForFrien(FriendRecordDto friend)
        {
            var isFriend= _friendsRepository.FindAll(a=>a.ConsumerId==friend.ProposerId&&a.FriendId==friend.RespondentId).Any();
            if (isFriend) throw new BusinessLogicException("已经是好友");
            var isStatue=currentRepository.FindAll(a=>a.ProposerId==friend.ProposerId&&a.FriendStatus==FriendStatusEnum.InThings).Any();
            if (isStatue) throw new BusinessLogicException("还存在未处理的好友申请");
            var data=_mapper.Map<FriendRecord>(friend);
            data.FriendStatus = FriendStatusEnum.InThings;
            data =await currentRepository.AddAsync(data);
            await unitOfWork.SaveChangesAsync();
            return data.Id;
        }

        public async Task<Tuple<IList<FriendRecordDto>,int>> GetFriendRecordsList(Guid userId, sbyte statue, int pageNo, int pageSize)
        {
            var data = await currentRepository.GetFieldQuery(a => a.RespondentId== userId && statue == -1 || a.FriendStatus == (FriendStatusEnum)statue,
                 a => new FriendRecordDto { Id = a.Id,FriendStatus=a.FriendStatus,ProposerId=a.ProposerId,Remark=a.Remark,RespondentId=a.RespondentId,Respondent=_mapper.Map<ConsumerDto>(a.Respondent)},a=>a.CreatedTime,pageNo,pageSize);
            return data;
        }
    }
}
